#ifndef MY_FOUROPERATOR_H
#define MY_FOUROPERATOR_H
#include <string>
#include <list>
using namespace std;
namespace MyFourOperator{
	enum EType{
		ET_Eq = 0x01, //=
		ET_LogicOr = 0x010, // ||
		ET_LogicAnd = 0x011, // &&
		ET_LogicEq = 0x012, // ==
		ET_LogicMo = 0x014,	// >
		ET_LogicLs = 0x018, // <
		ET_Or = 0x020, // |
		ET_And = 0x021, // &
		ET_Bitl = 0x022, // <<
		ET_Bitr = 0x024, // >>
		ET_Add = 0x040, // +
		ET_Sub = 0x041,	// -
		ET_Mul = 0x082, // *
		ET_Div = 0x084, // /
		ET_Cvr = 0x100, // !
		ET_BitCvr = 0x101, // ~
		ET_Number = 0x200,
		ET_End = 0x0
	};
	const char* GetSymbolDecl( EType et );
	class CToken{
	public:
		CToken( const char* pszExpression ) : m_iPos( 0 ), m_et( ET_End ), iValue( 0 ){ strExp = pszExpression; };
		CToken() : m_iPos( 0 ), m_et( ET_End ), iValue( 0 ){};
		void SetTokenSource( const char* pszExpression ){ m_iPos = 0; strExp = pszExpression; iValue = 0; m_et = ET_End; };
		EType GetNextToken();
		EType Token(){ return m_et; };
		int GetTokenValue(){ return iValue; };
	private:
		bool TestString( const char* str );
	private:
		int iValue;
		string strExp;
		int m_iPos;
		EType	m_et;
	};

	class CYS{
	public:
		CYS(){};
		int GetValue( const char* pszExps, int& oV );
	private:
		int Operation( EType et, int l, int r );
		int val1( int& oV );
		int Exp( int& oV );
		int ExpR( int l, EType etl, int& oV );
	private:
		CToken	m_token;
	};

	class CTest{
	public:
		struct TestTM{
			string strTestStr;
			int iResult;
		};
		CTest() : m_file( NULL ){};
		~CTest(){ if( m_file ) fclose( m_file ); };
		int ConstructTestEnv( const char* pszCheckFile );
		void Check();
	private:
		void clear(){ m_CheckTestList.clear(); };
		string GetLine();
	private:
		list< TestTM >	m_CheckTestList;
		FILE* m_file;
	};
};
#endif